from database import *
from flask import Flask, g
from flask import abort
from flask import request
from flask import Blueprint, current_app

LOG = config.getlogger()

command = Blueprint('command', __name__)


@command.route('/result/<client_uid>/<name>', methods=['POST'])
def reg_result(client_uid=None, name=None):
    pass


@command.route('/', methods=['GET'])
@command.route('/<client_uid>', methods=['GET'])
@command.route('/<client_uid>/<name>', methods=['GET'])
def command_status(client_uid=None, name=None):
    addr = request.args.get('addr', get_real_addr())
    filter = request.args.get('filter', 'all')
    query_result = db_session.query(Command).filter(Command.ip == addr)
    if client_uid:
        query_result = db_session.query(Command).filter(
            Command.clientuid == client_uid)
    if name:
        query_result = query_result.filter(Command.name == name)
    if filter == 'new':
        query_result = query_result.filter(Command.fetchtime == None)
    elif filter == 'running':
        query_result = query_result.filter(Command.fetchtime != None).filter(
            Command.finishtime == None)
    elif filter == 'finished':
        query_result = query_result.filter(Command.fetchtime != None).filter(
            Command.finishtime != None)
    result = defaultdict(dict)
    for i in query_result.all():
        data = dict({'content': i.content,
                     'result': i.result,
                     'error': i.error,
                     'createtime': i.createtime,
                     'fetchtime': i.fetchtime,
                     'starttime': i.starttime,
                     'finishtime': i.finishtime})
        if client_uid and name:
            result = data
        elif client_uid and not name:
            result[i.name] = data
        elif not client_uid and not name:
            result[i.clientuid][i.name] = data
    return json.dumps(result)


@command.route('/<client_uid>/<name>', methods=['POST'])
def do_command(client_uid=None, name=None):
    addr = request.form.get('addr', get_real_addr())
    signature = request.form['signature']
    method = request.form['method']
    ret = request.form.get('result', '')
    err = request.form.get('error', '')
    if client_uid is None or method is None or name is None:
        abort(400)
    try:
        query_result = db_session.query(Command).filter(Command.ip == addr)
        query_result = query_result.filter(Command.uid == client_uid)
        query_result = query_result.filter(Command.name == name)
        if method == 'fetch':
            query_result = query_result.filter(
                Command.starttime == None).filter(Command.finishtime == None)
            if query_result.count() != 1:
                abort(404)
            signature = signature(addr, name)
            fetchtime = int(time.time())
            i = query_result.one()
            i.fetchtime = fetchtime
            i.signature = signature
            db_session.commit()
            result = dict({'fetch_time': fetchtime, 'signature': signature})
            return json.dumps(result)
        elif method == 'start' and signature is not None:
            query_result = query_result.filter(
                Command.fetchtime != None).filter(
                    Command.signature == signature)
            if query_result.count() != 1:
                abort(404)
            starttime = int(time.time())
            i = query_result.one()
            i.starttime = starttime
            db_session.commit()
            result = dict({'start_time': starttime})
            return json.dumps(result)
        elif method == 'finish' and signature is not None:
            query_result = query_result.filter(
                Command.fetchtime != None).filter(
                    Command.starttime != None).filter(
                        Command.signature == signature)
            if query_result.count() != 1:
                abort(404)
            finishtime = int(time.time())
            i = query_result.one()
            i.finishtime = finishtime
            i.result = ret
            i.error = err
            db_session.commit()
            result = dict({'finish_time': finishtime})
            return json.dumps(result)
        abort(404)
    except Exception, ex:
        LOG.error("error %s", str(ex))
        db_session.rollback()
        abort(500)
